
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.XJ;
using Nop.Services.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;

namespace Nop.Services.XJ
{
	/// <summary>
	/// XJMaintenanceSchedule service
	/// </summary>
	public partial class XJMaintenanceScheduleService : IXJMaintenanceScheduleService
	{
		#region Constants

		/// <summary>
		/// Key for caching
		/// </summary>
		private const string XJMAINTENANCESCHEDULES_ALL_KEY = "Nop.xjmaintenanceschedule.all";
		/// <summary>
		/// Key for caching
		/// </summary>
		/// <remarks>
		/// {0} : xJMaintenanceSchedule ID
		/// </remarks>
		private const string XJMAINTENANCESCHEDULE_BY_ID_KEY = "Nop.xjmaintenanceschedule.id-{0}";
		/// <summary>
		/// Key pattern to clear cache
		/// </summary>
		private const string XJMAINTENANCESCHEDULES_PATTERN_KEY = "Nop.xjmaintenanceschedule.";
		#endregion

		#region Fields
		private readonly IRepository<XJMaintenanceSchedule> _xJMaintenanceScheduleRepository;
		private readonly IEventPublisher _eventPublisher;
		private readonly ICacheManager _cacheManager;
		#endregion

		#region Ctor

		/// <summary>
		/// Ctor
		/// </summary>
		/// <param name="cacheManager">Cache manager</param>
		/// <param name="xJMaintenanceScheduleRepository">XJMaintenanceSchedule repository</param>
		/// <param name="eventPublisher">Event published</param>
		public XJMaintenanceScheduleService(ICacheManager cacheManager,
			IRepository<XJMaintenanceSchedule> xJMaintenanceScheduleRepository,
			IEventPublisher eventPublisher)
		{
			this._cacheManager = cacheManager;
			this._xJMaintenanceScheduleRepository = xJMaintenanceScheduleRepository;
			this._eventPublisher = eventPublisher;
		}

		#endregion

		#region Methods

		/// <summary>
		/// Gets all XJMaintenanceSchedules
		/// </summary>
		/// <returns>XJMaintenanceSchedules</returns>
		public virtual IList<XJMaintenanceSchedule> GetAllXJMaintenanceSchedules()
		{
			string key = XJMAINTENANCESCHEDULES_ALL_KEY;
			return _cacheManager.Get(key, () =>
			{
				var query = from a in _xJMaintenanceScheduleRepository.Table
							orderby a.Id
							select a;
				return query.ToList();
			});
		}

		public virtual IPagedList<XJMaintenanceSchedule> GetXJMaintenanceSchedules(int maintenanceId, int pageIndex = 0, int pageSize = int.MaxValue)
		{
			var query = from a in _xJMaintenanceScheduleRepository.Table
						where a.MaintenanceId == maintenanceId
						orderby a.Id
						select a;
			query = query.OrderBy(c => c.Id);

			//paging
			return new PagedList<XJMaintenanceSchedule>(query, pageIndex, pageSize);
		}

		public virtual int GetTotalMinutes(int maintenanceId)
		{
			var query = from a in _xJMaintenanceScheduleRepository.Table
						where a.MaintenanceId == maintenanceId
						orderby a.Id
						select a.Minutes;
			if (null == query || query.Count() == 0)
				return 0;
			return query.Sum(m => m);
		}

		/// <summary>
		/// Gets a XJMaintenanceSchedule 
		/// </summary>
		/// <param name="xJMaintenanceScheduleId">XJMaintenanceSchedule identifier</param>
		/// <returns>XJMaintenanceSchedule</returns>
		public virtual XJMaintenanceSchedule GetXJMaintenanceScheduleById(int xJMaintenanceScheduleId)
		{
			if (xJMaintenanceScheduleId == 0)
				return null;

			string key = string.Format(XJMAINTENANCESCHEDULE_BY_ID_KEY, xJMaintenanceScheduleId);
			return _cacheManager.Get(key, () => _xJMaintenanceScheduleRepository.GetById(xJMaintenanceScheduleId));
		}

		/// <summary>
		/// Inserts a XJMaintenanceSchedule
		/// </summary>
		/// <param name="xJMaintenanceSchedule">XJMaintenanceSchedule</param>
		public virtual void InsertXJMaintenanceSchedule(XJMaintenanceSchedule xJMaintenanceSchedule)
		{
			if (xJMaintenanceSchedule == null)
				throw new ArgumentNullException("xJMaintenanceSchedule");

			_xJMaintenanceScheduleRepository.Insert(xJMaintenanceSchedule);

			_cacheManager.RemoveByPattern(XJMAINTENANCESCHEDULES_PATTERN_KEY);

			//event notification
			_eventPublisher.EntityInserted(xJMaintenanceSchedule);
		}

		public virtual void NewSchedule(XJMaintenanceSchedule xJMaintenanceSchedule)
		{
			if (xJMaintenanceSchedule == null)
				throw new ArgumentNullException("xJMaintenanceSchedule");

			var schedule = _xJMaintenanceScheduleRepository.Table.FirstOrDefault(m => m.MaintenanceId == xJMaintenanceSchedule.MaintenanceId && !m.EndOn.HasValue);
			if (schedule == null)
			{
				_xJMaintenanceScheduleRepository.Insert(xJMaintenanceSchedule);

				_cacheManager.RemoveByPattern(XJMAINTENANCESCHEDULES_PATTERN_KEY);

				//event notification
				_eventPublisher.EntityInserted(xJMaintenanceSchedule);
			}
		}

		/// <summary>
		/// Updates the XJMaintenanceSchedule
		/// </summary>
		/// <param name="xJMaintenanceSchedule">XJMaintenanceSchedule</param>
		public virtual void UpdateXJMaintenanceSchedule(XJMaintenanceSchedule xJMaintenanceSchedule)
		{
			if (xJMaintenanceSchedule == null)
				throw new ArgumentNullException("xJMaintenanceSchedule");

			_xJMaintenanceScheduleRepository.Update(xJMaintenanceSchedule);

			_cacheManager.RemoveByPattern(XJMAINTENANCESCHEDULES_PATTERN_KEY);

			//event notification
			_eventPublisher.EntityUpdated(xJMaintenanceSchedule);
		}

		/// <summary>
		/// Deletes a XJMaintenanceSchedule
		/// </summary>
		/// <param name="xJMaintenanceSchedule">XJMaintenanceSchedule</param>
		public virtual void DeleteXJMaintenanceSchedule(XJMaintenanceSchedule xJMaintenanceSchedule)
		{
			if (xJMaintenanceSchedule == null)
				throw new ArgumentNullException("xJMaintenanceSchedule");

			_xJMaintenanceScheduleRepository.Delete(xJMaintenanceSchedule);

			_cacheManager.RemoveByPattern(XJMAINTENANCESCHEDULES_PATTERN_KEY);

			//event notification
			_eventPublisher.EntityDeleted(xJMaintenanceSchedule);
		}

		#endregion
	}
}
